﻿using System;
using System.Collections.Generic;
using System.Reflection;
using Core.Model;
using Core.Model.Transmit;
using Core.Msg;
using log4net;

namespace Core.Transmit
{
    public abstract class TransmitDeviceProtocol
    {
        protected static readonly ILog _log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
        public TransmitChannelProtocol Channel { get; protected set; }
        public TransmitDevice Dev { get; protected set; }
        public List<TransmitData> TransDataItems { get; } = new List<TransmitData>();
        public virtual bool Initialize(TransmitChannelProtocol channel, TransmitDevice dev,List<TransmitData> dataItems)
        {
            Channel = channel;
            Dev = dev;
            if (dataItems != null && dataItems.Count > 0)
            {
                TransDataItems.Clear();
                TransDataItems.AddRange(dataItems);
            }
            if(Dev!= null)
                Dev.PropertyChanged += Dev_PropertyChanged;
            return true;
        }

        private void Dev_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "IsConnected")
            {
                if (!Dev.IsConnected)
                {
                    foreach (TransmitData item in TransDataItems)
                    {
                        item.CurValue = 0;
                    }
                }
                else
                {
                    foreach (TransmitData item in TransDataItems)
                    {
                        item.UpdateTime = DateTime.Now;
                    }
                }
            }
        }

        protected void MsgLog(bool error, string content)
        {
            if(error)
                _log.Error(content);
            else
                _log.Info(content);
        }
     
       
        public virtual bool LoadDataItems()
        {
            List<TransmitData> dataItems = Global.DataAccess.GetTransmitData(Dev.Id);
            if (dataItems == null)
                return false;
            TransDataItems.Clear();
            TransDataItems.AddRange(dataItems);
            return true;
        }

        public virtual List<TransmitData> SerializeDataItems(List<TransmitData> items)
        {
            if (items != null && items.Count > 0 && items[0].TagObject!=null)
            {
                foreach (TransmitData item in items)
                {
                    item.SubInfo = Newtonsoft.Json.JsonConvert.SerializeObject(item.TagObject);
                }
            }
            return items;
        }

        public virtual List<TransmitData> DeSerializeDataItems(List<TransmitData> items)
        {
            if (items != null && items.Count > 0 && !string.IsNullOrEmpty(items[0].SubInfo))
            {
                foreach (TransmitData item in items)
                {
                    item.TagObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Extra>(item.SubInfo);
                }
            }
            return items;
        }

        public virtual TransmitData DeSerializeDataItem(TransmitData item)
        {
            item.TagObject = Newtonsoft.Json.JsonConvert.DeserializeObject<Extra>(item.SubInfo);
            return item;
        }

        protected List<TransmitData> DeSerialize<T>(List<TransmitData> items) where T : Extra
        {
            if (items != null && items.Count > 0 && !string.IsNullOrEmpty(items[0].SubInfo))
            {
                foreach (TransmitData item in items)
                {
                    item.TagObject = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(item.SubInfo);
                }
            }
            return items;
        }

        protected TransmitData DeSerialize<T>(TransmitData item) where T : Extra
        {
            item.TagObject = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(item.SubInfo);
            return item;
        }
        public virtual TransmitData DecorateItem(TransmitData item)
        {
            return item;
        }

        public virtual bool TryReplyCommand(byte[] clientBuffer, out byte[] replyBuffer)
        {
            replyBuffer = null;
            return false;
        }

    }
}
